package com.ethink.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ethink.framework.common.constant.CommonRespCode;
import com.ethink.framework.common.db.PageUtils;
import com.ethink.framework.common.exception.BusinessException;
import com.ethink.id.generator.IdGenerator;
import com.ethink.order.api.constant.OrderRespCode;
import com.ethink.order.api.enums.SaleDemandDetailOrderStatusEnum;
import com.ethink.order.api.enums.SaleDemandOrderOrderStatusEnum;
import com.ethink.order.api.info.PurchaseOrderSaleInfo;
import com.ethink.order.api.info.SaleDemandOrderDetailInfo;
import com.ethink.order.api.info.SaleDemandOrderInfo;
import com.ethink.order.api.model.OrderConfirmModel;
import com.ethink.order.api.request.*;
import com.ethink.order.api.response.SaleDemandOrderDetailAddResponse;
import com.ethink.order.api.response.SaleDemandOrderDetailDeleteResponse;
import com.ethink.order.api.response.SaleDemandOrderDetailUpdateResponse;
import com.ethink.order.api.utils.EthinkStrUtil;
import com.ethink.order.common.entity.SaleDemandOrderDetail;
import com.ethink.order.common.mapper.SaleDemandOrderDetailMapper;
import com.ethink.order.converter.SaleDemandOrderDetailConverter;
import com.ethink.order.manager.PublicManager;
import com.ethink.order.service.SaleDemandOrderDetailService;
import com.ethink.order.service.SaleDemandOrderService;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 销售需求详情单 Service接口实现
 *
 * @author default
 * @date 2022-10-31
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class SaleDemandOrderDetailServiceImpl extends ServiceImpl<SaleDemandOrderDetailMapper, SaleDemandOrderDetail> implements SaleDemandOrderDetailService {

    @Autowired
    private SaleDemandOrderDetailMapper saleDemandOrderDetailMapper;

    @Autowired
    private SaleDemandOrderDetailConverter saleDemandOrderDetailConverter;

    @Autowired
    private SaleDemandOrderService saleDemandOrderService;

    @Autowired
    private PublicManager publicManager;

    @Autowired
    private IdGenerator idGenerator;

    @Override
    public Page<SaleDemandOrderDetailInfo> querySaleDemandOrderDetail(SaleDemandOrderDetailQueryRequest request) {
        return saleDemandOrderDetailMapper.querySaleDemandOrderDetail(PageUtils.buildPage(request), request);
    }

    @Override
    public SaleDemandOrderDetailInfo getSaleDemandOrderDetailById(Long saleDemandOrderDetailId) {
        return saleDemandOrderDetailMapper.getSaleDemandOrderDetailById(saleDemandOrderDetailId);
    }

    @Override
    public List<SaleDemandOrderDetailInfo> listSaleDemandOrderDetail(SaleDemandOrderDetailQueryRequest request) {
        return saleDemandOrderDetailMapper.listSaleDemandOrderDetail(request);
    }

    @Override
    public SaleDemandOrderDetailAddResponse addSaleDemandOrderDetail(SaleDemandOrderDetailAddRequest request, String orderNo
            , BigDecimal exchange, BigDecimal defaultTaxRate) {
        SaleDemandOrderDetailAddResponse response = new SaleDemandOrderDetailAddResponse();
        SaleDemandOrderDetail saleDemandOrderDetail = new SaleDemandOrderDetail();
        if (request.getExceptSalePriceTax() != null) {
            request.setExceptSalePriceNoTax(publicManager.noTaxCal(request.getExceptSalePriceTax(), request.getTaxRate(), request.getDiscount()));
            request.setExceptSalePriceTaxLocal(publicManager.mult(request.getExceptSalePriceTax(), exchange));
            request.setExceptSalePriceNoTaxLocal(publicManager.mult(request.getExceptSalePriceNoTax(), exchange));
        }
        //生成随机单号
        String detailOrderNo = idGenerator.xqDetail();
        BeanUtils.copyProperties(request, saleDemandOrderDetail);
        saleDemandOrderDetail.setDetailOrderNo(detailOrderNo);
        saleDemandOrderDetail.setOrderNo(orderNo);
        String cateName = EthinkStrUtil.stitchStrings(request.getGeneraCodeName(), request.getMinorDefectsCodeName(), request.getSubclassCodeName());
        saleDemandOrderDetail.setCategoryName(cateName);
        saleDemandOrderDetail.setExceptGrossProfit(publicManager.computeRate(request.getExceptSalePriceNoTaxLocal(), request.getTargetCostLocal()));
        saleDemandOrderDetailMapper.insert(saleDemandOrderDetail);
        return response;
    }

    @Override
    public SaleDemandOrderDetailUpdateResponse updateSaleDemandOrderDetail(SaleDemandOrderDetailUpdateRequest request) {
        SaleDemandOrderDetailUpdateResponse response = new SaleDemandOrderDetailUpdateResponse();
        LambdaUpdateWrapper<SaleDemandOrderDetail> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SaleDemandOrderDetail::getId, request.getId());
     /*   updateWrapper.set(SaleDemandOrderDetail::getOrderNo, request.getOrderNo());
        updateWrapper.set(SaleDemandOrderDetail::getDetailOrderNo, request.getDetailOrderNo());
        updateWrapper.set(SaleDemandOrderDetail::getIsLock, request.getIsLock());
        updateWrapper.set(SaleDemandOrderDetail::getMateCode, request.getMateCode());
        updateWrapper.set(SaleDemandOrderDetail::getMateName, request.getMateName());
        updateWrapper.set(SaleDemandOrderDetail::getMateSku, request.getMateSku());
        updateWrapper.set(SaleDemandOrderDetail::getMateSkuName, request.getMateSkuName());
        updateWrapper.set(SaleDemandOrderDetail::getGeneraCode, request.getGeneraCode());
        updateWrapper.set(SaleDemandOrderDetail::getMinorDefectsCode, request.getMinorDefectsCode());
        updateWrapper.set(SaleDemandOrderDetail::getSubclassCode, request.getSubclassCode());
        updateWrapper.set(SaleDemandOrderDetail::getBrandCode, request.getBrandCode());
        updateWrapper.set(SaleDemandOrderDetail::getBrandName, request.getBrandName());
        updateWrapper.set(SaleDemandOrderDetail::getInternationCode, request.getInternationCode());
        updateWrapper.set(SaleDemandOrderDetail::getUnitCode, request.getUnitCode());
        updateWrapper.set(SaleDemandOrderDetail::getUnitName, request.getUnitName());
        updateWrapper.set(SaleDemandOrderDetail::getDemandQty, request.getDemandQty());
        updateWrapper.set(SaleDemandOrderDetail::getDemandAffirmQty, request.getDemandAffirmQty());
        updateWrapper.set(SaleDemandOrderDetail::getExceptGrossProfit, request.getExceptGrossProfit());*/
        saleDemandOrderDetailMapper.update(null, updateWrapper);
        return response;
    }

    @Override
    public SaleDemandOrderDetailDeleteResponse deleteSaleDemandOrderDetail(Long saleDemandOrderDetailId) {
        SaleDemandOrderDetailDeleteResponse response = new SaleDemandOrderDetailDeleteResponse();
        LambdaUpdateWrapper<SaleDemandOrderDetail> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SaleDemandOrderDetail::getId, saleDemandOrderDetailId);
        updateWrapper.set(SaleDemandOrderDetail::getIsDeleted, true);
        saleDemandOrderDetailMapper.update(null, updateWrapper);
        return response;
    }

    @Override
    public void batchInsert(List<SaleDemandOrderDetailAddRequest> item, String orderNo, BigDecimal exchangeRate, BigDecimal defaultTaxRate) {

        for (SaleDemandOrderDetailAddRequest saleDemandOrderDetailAddRequest : item) {
            addSaleDemandOrderDetail(saleDemandOrderDetailAddRequest, orderNo, exchangeRate, defaultTaxRate);
        }
    }

    @Override
    public void demandConfirm(SaleDemandOrderConfirmRequest request) {
        List<Long> ids = CollUtil.getFieldValues(request.getItem(), "id", Long.class);
        List<SaleDemandOrderDetail> details = saleDemandOrderDetailMapper.selectBatchIds(ids);
        Map<Long, Integer> map = request.getItem().stream()
                .collect(Collectors.toMap(OrderConfirmModel::getId, OrderConfirmModel::getDemandAffirmQty, (a, b) -> a));
        for (SaleDemandOrderDetail detail : details) {
            Integer confirmNum = map.get(detail.getId());
            if (detail.getDemandQty() < confirmNum) {
                throw new BusinessException(CommonRespCode.SYSTEM_ERR.getCode(), "确认数量不能大于需求数量");
            }
        }
        for (OrderConfirmModel orderConfirmModel : request.getItem()) {
            saleDemandOrderDetailMapper.update(null
                    , new LambdaUpdateWrapper<SaleDemandOrderDetail>()
                            .eq(SaleDemandOrderDetail::getId, orderConfirmModel.getId())
                            .set(SaleDemandOrderDetail::getDemandAffirmQty, orderConfirmModel.getDemandAffirmQty()));
        }
        saleDemandOrderService.updateStatus(request.getOrderNo(), SaleDemandOrderOrderStatusEnum.S3.getIntValue());
    }

    @Override
    public String lock(SaleDemandOrderLockRequest request) {
        SaleDemandOrderDetail saleDemandOrderDetail = saleDemandOrderDetailMapper.selectById(request.getId());
        //修改状态
        saleDemandOrderDetail.setExceptSalePriceTax(request.getExceptSalePriceTax());
        saleDemandOrderDetail.setExceptSalePriceNoTax(request.getExceptSalePriceNoTax());
        saleDemandOrderDetail.setExceptSalePriceNoTaxLocal(request.getExceptSalePriceNoTaxLocal());
        saleDemandOrderDetail.setExceptSalePriceTaxLocal(request.getExceptSalePriceTaxLocal());
        saleDemandOrderDetail.setTargetCostLocal(request.getTargetCostLocal());
        saleDemandOrderDetail.setAveragePurchasePrice(request.getAveragePurchasePrice());
        //计算毛利率
        if (request.getAveragePurchasePrice().compareTo(BigDecimal.ZERO) != 0) {
            saleDemandOrderDetail.setExceptGrossProfit(publicManager.computeRate(request.getExceptSalePriceNoTaxLocal(), request.getAveragePurchasePrice()));
        }
        saleDemandOrderDetail.setDetailOrderStatus(SaleDemandDetailOrderStatusEnum.S2.getIntValue());
        saleDemandOrderDetail.setIsLock(true);
        saleDemandOrderDetailMapper.updateById(saleDemandOrderDetail);
        return saleDemandOrderDetail.getDetailOrderNo();
    }

    @Override
    public void unlock(Long id) {
        SaleDemandOrderDetail saleDemandOrderDetail = saleDemandOrderDetailMapper.selectById(id);
        saleDemandOrderDetailMapper.update(null
                , new LambdaUpdateWrapper<SaleDemandOrderDetail>()
                        .eq(SaleDemandOrderDetail::getId, id)
                        .set(SaleDemandOrderDetail::getIsLock, false)
                        .set(SaleDemandOrderDetail::getDetailOrderStatus, SaleDemandDetailOrderStatusEnum.S1.getIntValue()));

    }

    @Override
    public SaleDemandOrderDetailInfo queryByDetailOrderNo(String detailOrderNo) {
        SaleDemandOrderDetail saleDemandOrderDetail = saleDemandOrderDetailMapper.selectOne(new LambdaQueryWrapper<SaleDemandOrderDetail>()
                .eq(SaleDemandOrderDetail::getDetailOrderNo, detailOrderNo));
        return saleDemandOrderDetailConverter.convertFrom(saleDemandOrderDetail);
    }

    @Override
    public void bulkUpdate(List<SaleDemandOrderDetailUpdateRequest> item, String orderNo) {
        if (CollUtil.isEmpty(item)) {
            return;
        }
        List<SaleDemandOrderDetail> details = new ArrayList<>();
        SaleDemandOrderDetail demandOrderDetail;
        for (SaleDemandOrderDetailUpdateRequest request : item) {
            demandOrderDetail = new SaleDemandOrderDetail();
            BeanUtil.copyProperties(request, demandOrderDetail);
            demandOrderDetail.setOrderNo(orderNo);
            if (request.getId() == null) {
                demandOrderDetail.setDetailOrderNo(idGenerator.xqDetail());
                String cateName = EthinkStrUtil.stitchStrings(request.getGeneraCodeName(), request.getMinorDefectsCodeName(), request.getSubclassCodeName());
                demandOrderDetail.setCategoryName(cateName);
            }
            demandOrderDetail.setExceptGrossProfit(publicManager.computeRate(request.getExceptSalePriceNoTaxLocal(), request.getTargetCostLocal()));
            details.add(demandOrderDetail);
        }
        saveOrUpdateBatch(details);
    }

    @Override
    public SaleDemandOrderDetailInfo queryItemByDetailOrderNo(String detailOrderNo) {
        SaleDemandOrderDetail saleDemandOrderDetail = saleDemandOrderDetailMapper.selectOne(new LambdaQueryWrapper<SaleDemandOrderDetail>()
                .eq(SaleDemandOrderDetail::getDetailOrderNo, detailOrderNo));
        return saleDemandOrderDetailConverter.convertFrom(saleDemandOrderDetail);
    }

    @Override
    public List<PurchaseOrderSaleInfo> queryExceptSalePriceTaxLocal(List<String> purchaseDetailOrderNoList) {
        return saleDemandOrderDetailMapper.queryExceptSalePriceTaxLocal(purchaseDetailOrderNoList);
    }

    @Override
    public SaleDemandOrderInfo queryMainByDetailId(Long id) {
        SaleDemandOrderDetail saleDemandOrderDetail = saleDemandOrderDetailMapper.selectById(id);
        return saleDemandOrderService.queryMainByOrderNo(saleDemandOrderDetail.getOrderNo());
    }
}
